
//  请求模块
import axios from 'axios'
import store from '@/store/'
import router from '@/router/'
import JSONnBig from 'json-bigint'
import { Toast } from 'vant'

const request = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/', // 基础路径
  // baseURL: 'https://toutiao.m.lipengzhou.com/api/', // 基础路径
  transformResponse: [function (data) {
    // 后端返回的响应数据可能不是JSON格式
    // 如果不是的话, JSONbig.parse调佣就会报错
    // 所以我们需要用try-catch来捕获异常, 处理异常的发生
    try {
      // 如果转换成功则返回转换的数据结果
      return JSONnBig.parse(data)
    } catch (err) {
      // 如果转换失败，则进入这里
      // 我们在这里把数据原封不动的直接返回给请求使用
      return data
    }
  }]
})

// 重新创建一个实例, 重新刷新token(不走request实例), 拦截器
const refreshTokenReq = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/'
})

// 请求拦截器
request.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  if (store.state.user) {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 响应拦截器
request.interceptors.response.use(function (response) {
  // Any status code that lie within the range of 2xx cause this function to trigger
  // Do something with response data
  return response
}, async function (error) {
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // Do something with response error
  const status = error.response.status
  if (status === 400) {
    // 客户端参数错误
    Toast.fail('客户端请求参数异常')
  } else if (status === 401) {
    // token 无效
    const { user } = store.state
    // 如果没有 user 或者 user.token, 直接去登录
    if (!user || !user.token) {
      return redirectLogin()
    }
    // 如果有refresh_token, 则请求获取新的token
    try {
      // 刷新用户token 和登录接口不一样(使用refresh_token), 如果使用request实例发请求, 会重新走拦截器, 如果在401, 会死循环
      const { data } = await refreshTokenReq({
        url: 'app/v1_0/authorizations',
        method: 'PUT',
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })
      // 如果刷新token成功, 把token更新到容器中
      user.token = data.data.token
      store.commit('setUser', user)
      // 把失败的请求用request实例重新发回去
      // error.config 是本次请求的配置对象
      return request(error.config)
    } catch (err) {
      // 刷新token都失败了, 直接跳转登录页
      return redirectLogin()
    }
    // 拿到新的token之后重新更新到容器中
    //  把失败的请求重新发送回去
  } else if (status === 403) {
    // 没有权限
    Toast.fail('没有操作权限')
  } else if (status >= 500) {
    // 服务器错误
    Toast.fail('服务器异常, 请稍后重试')
  }
  return Promise.reject(error)
})

// 跳转登录页面
function redirectLogin () {
  // 传递的查询参数, 查询参数会以 ? 作为分隔符放到url中
  router.replace({
    name: 'login',
    query: {
      // router.currentRoute: 和我们在组件中 this.$route是一个东西
      redirect: router.currentRoute.fullPath
    }
  })
}
// 导出
export default request
